<?php


class DB {

	private $db = null;
	private $res = null;
	private static $instance;

	private function __construct() {}

	public static function getDBInstance() {
		
		if (!(self::$instance instanceof self)) {

			self::$instance = new self();

			self::$instance->db = mysqli_init();
			if (! self::$instance->db) {
				self::$instance->saveDBError('mysqli_init failed');
				return false;
			}

			if (! self::$instance->db->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5)) {
				self::$instance->saveDBError('Setting MYSQLI_INIT_COMMAND failed');
				return false;
			}

			if (! self::$instance->db->real_connect(MYSQL_CONN_HOST, MYSQL_CONN_USER, MYSQL_CONN_PASSWD, MYSQL_CONN_DB, MYSQL_CONN_PORT)) {
				self::$instance->saveDBError('Connect Error (' . mysqli_connect_errno() . ') ' . mysqli_connect_error());
				return false;
			}

			if (! self::$instance->db->set_charset('utf8')) {
				self::$instance->saveDBError('Error loading character set utf8:' . self::$instance->error());
				return false;
			}

			self::$instance->res = null;

			return self::$instance;
		}
	}

	private function saveDBError($msg, $type='MySQL') {
		
		$time = date("Y-m-d H:i:s");
		$msg = $type . " 数据提示信息：" . $msg . "\r\n";
		$file_path = PHPLOG_PATH . "/error/mysql.log";
		$file = PHPLOG_PATH . "/error/";

		if (! file_exists($file)) {
			@mkdir($file, 0777);
		}

		file_put_contents($file_path, $msg, FILE_APPEND);
	}

	public function query($sql) {
	
		$this->res = $this->db->query($sql);
		if ($this->res === FALSE) { # 查询失败
			$this->saveDBError($sql, 'SQL');
			return null;
		}
	}

	// 获取结果集
	public function result_array() {
		if ($this->res->num_rows > 0) {
			//return $this->res->fetch_all(MYSQLI_NUM);
			while ($tmp = $this->res->fetch_array(MYSQLI_ASSOC)) {
				$row[] = $tmp;
			}
			return $row;

		} else {
			return null;
		}
	}

	// 获取单行结果
	public function row_array() {
		if ($this->res->num_rows > 0) {
			return  $this->res->fetch_row(MYSQLI_ASSOC);
		} else {
			return null;
		}
	}

	// 返回最后插入记录时的ID号
	public function insertId($name = null) {
		return $this->db->insert_id;
	}

	// 影响的行数
	public function affected_rows() {
		return $this->db->affected_rows;
	}

	public function saveSQLError($table = null, $sql = null, $message = null) {
	
		$time = date("Y-m-d H:i:s");			// 将当前时间格式化输出
		$message = "SQL 错误的表名或SQL语句:\r\n$table" . "\r\n错误的查询语句:\r\n$sql" . "\r\n数据库错误提示信息:\r\n$message" . "\r\n\r\n";

		$file_path = PHPLOG_PATH . "/error/mysql.log";
		$file = PHPLOG_PATH . "/error/";
		if (! file_exists($file)) {
			@mkdir($file, 0777);
		}

		file_put_contents($file_path, $message, FILE_APPEND);
	}

	public function insert($table, $key_value_arr = null) {

		try {
			foreach ($key_value_arr as $key => $value) {
				$keys .= "`$key`,";
				$values .= "'" . $this->db->real_escape_string($value) . "',";
				//$values 	.= "'$value',";
			}

			$keys = substr($keys, 0, -1);
			$values = substr($values, 0, -1);
			$sql = "INSERT INTO `$table` ($keys) VALUES($values)";
			$this->query($sql);
		} catch(mysqli_sql_exception $e) {
			$this->saveSQLError($table, $sql, $e->errorMessage());
			return false;
		} 
	}

	public function update($table, $key_value_arr = null, $field_value_arr = null) {
		try {
			if (is_array($key_value_arr)) {
				foreach ($key_value_arr as $key => $val) {
					//$query .= "`$key` = '$val',";
					$query .= "`$key` = '$this->db->real_escape_string($val)',";
				}
				$query = substr($query, 0, -1);
				if (is_array($field_value_arr)) {
					foreach ($field_value_arr as $fkey => $fvalue) {
						//$where .= "`$fkey` = '$fvalue' AND ";
						$where .= "`$fkey` = '$this->db->real_escape_string($fvalue)' AND ";
					}
					$where	=	substr(trim($where), 0, -3);
					$query	= "UPDATE `$table` SET $query WHERE $where";
				} else {
					$query	= "UPDATE `$table` SET $query WHERE $field_value_arr";
				}
			} else if (is_string($key_value_arr)) {
				if (is_array($field_value_arr)) {
					foreach ($field_value_arr as $fkey => $fvalue) {
						//$where .= "`$fkey` = '$fvalue' AND ";
						$where .= "`$fkey` = '$this->db->real_escape_string($fvalue)' AND ";
					}
					$where	=	substr(trim($where), 0, -3);
					$query	= "UPDATE `$table` SET $key_value_arr WHERE $where";

				} else {
					$query	= "UPDATE `$table` SET $key_value_arr WHERE $field_value_arr";
				}
			}

			$this->query($query);
		} catch(mysqli_sql_exception $e) {
			$this->saveSQLError($table, $query, $e->errorMessage());
			return false;
		} 
	}

	public function delete($table, $field = null, $value = null, $field_value_arr = null) {
		try {
			if (is_array($value)) {
				$value1 = implode(",",$value);
				$query = "DELETE FROM `$table` WHERE `$field` IN ($value1)";
			} else if (is_string($value)) {
				$value1 = implode(",",$value);
				$query = "DELETE FROM `$table` WHERE `$field` IN ($value1)";
			} else if (is_array($field_value_arr)) {
				foreach ($field_value_arr as $fkey => $fvalue) {
					//$query .= "`$fkey` = '$fvalue' and ";
					$query .= "`$fkey` = '$this->db->real_escape_string($fvalue)' and ";
				}

				$query = substr(trim($query), 0, -3);
	    		$query = "DELETE FROM `$table` WHERE $query";
			}
			$this->query($query);
		} catch(mysqli_sql_exception $e) {
			$this->saveSQLError($table, $query, $e->errorMessage());
			return false;
		} 
	}

	/**
	 * 查询
	 * @param $table 表名或SQL查询语句。表名不能为select
	 * @param $where 类型为array或字符串，条件语句,即where语句。
	 * @param $order 需要进行降序的字段，数据库默认为升序，所以，这里只需要指名需要进行降序的字段即可，字段只能为一个
	 * @param $offset 结果集中第一条记录的下标，用于分页用,默认值为空
	 * @param $count 结果集记录条数
	 * @param $orand 与或条件，默认值为且，此参数可以用来做并列查询或非并列查询
	 * @return 返回一个查询结果集
	 */
	public function select($table, $where = null, $order = null, $offset = null, $count = null, $orand = 'AND') {
		try {

			$sql = "SELECT * FROM `$table`";
			if ($where) {
	        	if (is_array($where)) {
		        	$orand = strtolower($orand);

		        	$sql = $sql . ' where';
		        	foreach ($where as $key => $val) {
						//$sql .= " `$key` = '$val' $orand";
						$sql .= " `$key` = '$this->db->real_escape_string($val)' $orand";
		        	}

		      		if ($orand = 'and') {
		        		$sql = substr($sql, 0, -3);
		        	} else if($orand = 'or') {
		        		$sql = substr($sql, 0, -2);
		        	}
	        	} else if (is_string($where)) {
					$sql = $sql . '  ' . $where;						
	        	}
	        }
	        if ($order) {
				$sql .= ' ' . $order ;
	        }
	        if (isset($offset) && isset($count)) {
				$sql .= " limit $offset, $count";
	        }

	        $this->query($sql);

		} catch(mysqli_sql_exception $e) {
			$this->saveSQLError($table, $query, $e->errorMessage());
			return false;
		}
	}

}

?>
